; ReadDisk(LPVOID lpDstBuf, DWORD dwLBA, DWORD dwSectors)
; 读取主磁盘上若干扇区
; @param dwSectors 读取的扇区数（取值范围：0 ~ 255，其中 0 表示读取 256 个扇区）
; @param lpDstBuf 指向读取缓冲区
; @param dwLBA 读取的起始扇区（LBA 方式）
; @remark 本函数不处理异常情况，只能在 bootloader 中使用（如：加载 Kernel 到内存），需要由调用者保证传入的参数不引发异常

%ifndef ReadDisk_asm
%define ReadDisk_asm
extern ReadSector
; 最多可尝试 9 次
%define lpDstBuf dword [ebp + 8]
%define dwLBA    dword [ebp + 12]
%define dwSectors dword [ebp + 16]
bits 32
global ReadDisk
ReadDisk:
    push ebp
    mov ebp, esp
    push es
    mov ecx, dwSectors ; 待读取扇区数 
ReadDisk.Loop:
    push dwLBA
    push lpDstBuf
    mov eax, 2 << 3
    mov es, eax
    call ReadSector ; 读取一个扇区
    add esp, 8 ; 弹出栈顶参数
    jc ReadDisk.Error
    ; 更新读磁盘参数
    add lpDstBuf, 512 ; 缓冲区起始位置后移 512 字节，为一扇区大小
    inc dwLBA ; 下一个 LBA 扇区
    loop ReadDisk.Loop
    mov eax, 0
ReadDisk.Return:
    pop es
    pop ebp
    ret
ReadDisk.Error:
    mov eax, 1
    jmp ReadDisk.Return
%undef dwSectors
%undef lpDstBuf
%undef dwLBA
%endif ; ReadDisk_asm